open Base
open Unique_id.Ids

type value = Dyn.t
type values = value Src_id.map
type effect = (value -> value) Src_id.map

let empty_values : values =
  Src_id.empty_map

let empty_effect : effect =
  Src_id.empty_map

let single_effect src f : effect =
  Map.singleton (module Src_id) src f

let merge_effect : effect -> effect -> effect =
  Map.merge_skewed ~combine:(fun ~key:_ -> Fn.compose)

let apply_effect values effect =
  let modify1 ~key:src ~data:fn vs =
    Map.update vs src
      ~f:(fun v -> fn (Option.value_exn v))
  in
  Map.fold effect ~init:values ~f:modify1
